/**
 * 在 TypeScript 函数里，如果我们定义了参数，则我们必须传入这些参数，
 * 除非将这些参数设置为可选，可选参数使用问号标识 ？。
 * 可选参数必须跟在必需参数后面。如果都是可选参数就没关系。
 */
function buildName(firstName: string, lastName?: string) {
  if (lastName) return firstName + " " + lastName;
  else return firstName;
}

let result1 = buildName("Bob"); // 正确
//let result2 = buildName("Bob", "Adams", "Sr.");  错误，参数太多了
let result3 = buildName("Bob", "Adams"); // 正确

/**
 *  剩余参数
 * 有一种情况，我们不知道要向函数传入多少个参数，这时候我们就可以使用剩余参数来定义。
 * 剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。
 * 函数的最后一个命名参数 restOfName 以 ... 为前缀，
 * 它将成为一个由剩余参数组成的数组，索引值从0（包括）到 restOfName.length（不包括）。
 */
function buildName1(firstName: string, ...restOfName: any[]) {
  return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName1("Joseph", 80, "Lucas", "MacKinzie");
console.log(employeeName);

/**
 * 构造函数
 */
var myFunction = new Function("a", "b", "return a * b");
var xx = myFunction(4, 3);
console.log(xx);

/**
 * 箭头函数 lambda
 */
var foo = (x: number) => 10 + x;
console.log(foo(100));

/**
 * 函数重载
 * 重载是方法名字相同，而参数不同，返回类型可以相同也可以不同。
 * 每个重载的方法（或者构造函数）都必须有一个 独一无二的参数类型 列表。
 */

function disp(s1: string): void;
function disp(n1: number, s1: string): void;

function disp(x: any, y?: any): void {
  console.log(x);
  console.log(y);
}
disp("abc");
disp(1, "xyz");
